using Gtk; 
using Gee;

namespace Atlantis
{
    public class TabWorkspace : GLib.Object, IWorkspace, IInjectRegistry
    {
        Notebook notebook;
        Registry registry;
        HashMap<GLib.Object,int> index;
        private GLib.Object selectedSmartPart;
		//public signal void SelectedSmartPartChanged(IWorkspace sender, GLib.Object SelectedSmartPart);
		
        public GLib.Object SelectedSmartPart 
        { 
            get
            {
                return selectedSmartPart;
            }  
            set
            {
				if (this.selectedSmartPart != value)
				{
					this.selectedSmartPart = value;
					this.notebook.set_current_page(index[value]);
					SelectedSmartPartChanged(this, selectedSmartPart);
				}
            }
        }

        public Registry Registry
        {
            get
            {
                return this.registry;
            }
            set
            {
                this.registry = value;
            }
        }

        public TabWorkspace(Notebook notebook)
        {
            index = new HashMap<GLib.Object, int>(GLib.direct_hash,GLib.str_equal);
            stderr.printf("TabWorkspace(Notebook notebook)\n");
            this.notebook = notebook;
            this.notebook.switch_page.connect( OnChangeCurrentPage );
            
            /* Individual style for the tab close buttons */
			rc_parse_string(
				"style \"hidalgo-close-tab-button-style\" {\n" +
				"	GtkWidget::focus-padding = 0\n" +
				"	GtkWidget::focus-line-width = 0\n" +
				"	xthickness = 0\n" + 
				"	ythickness = 0\n" +
				"}\n" +
				"widget \"*.hidalgo-close-tab-button\" style \"hidalgo-close-tab-button-style\""
			);
        }

        public void OnChangeCurrentPage(NotebookPage page, uint page_num)
        {
			stderr.printf("looking for pageIndex %d\n", (int)page_num);
            foreach (var item in index)
            {
				if (item.value == page_num)
				{
					Activate(item.key);
					stderr.printf("found pageIndex %d\n", (int)page_num);
				}
			}
        }

        ~TabWorkspace()
        {
            stderr.printf("~TabWorkspace()\n");
        }

        public void Activate(GLib.Object smartpart)
        {
            SelectedSmartPart = smartpart;
        }
		
        public void Add(GLib.Object smartpart)
        {
            stderr.printf("tabworkspace.Add(Widget smartpart)\n");
            Gtk.Widget widget = ExtractWidget(smartpart);
            
            string labelText = "Unknown";
            if (smartpart is ISmartPartInfoProvider)
            {
                stderr.printf("(smartpart is ISmartPartInfoProvider)\n");
                ISmartPartInfo smartPartInfo = ((ISmartPartInfoProvider)smartpart).GetSmartPartInfo();
                labelText = smartPartInfo.Label;
                stderr.printf("labelText = smartPartInfo.Label\n");
            }
            
            if (widget == null)
                stderr.printf("widget == null\n");

			//
			// Initialize the notebookpage
			//
            Widget label = create_notebook_label(labelText, notebook, 0);
            widget.show_all();
            int tabIndex = notebook.append_page(widget, label);
            if (tabIndex < 0)
            { 
                stderr.printf("failed to add a page\n");
            }
            else
            {
                stderr.printf("page should be added\n");
                index.set(smartpart, tabIndex);
            }
        }
        
        private Gtk.Widget create_notebook_label(string text, Gtk.Widget notebook, int page)
		{
			
			var label = new Label (null);
			var ebox = new EventBox();
			ebox.set_flags(WidgetFlags.NO_WINDOW);
			var hbox = new Gtk.HBox(false, 2);
			hbox.pack_start (label, false, false, 0);
			ebox.add(hbox);
			
			Gtk.Button button = new Gtk.Button ();
			button.relief = ReliefStyle.NONE;
			button.name = "hidalgo-close-tab-button";
			
			/* don't allow focus on the close button */
			button.set_focus_on_click (false);

			var image = new Image.from_stock(STOCK_CLOSE, IconSize.MENU);
			button.add(image);
			
			Alignment align = new Alignment(1.0f, 0.0f, 0.0f, 0.0f);
			align.add(button);
			hbox.pack_start (align, true, true, 0);
			
			 /* Set minimal size */
			button.style_set.connect ((s, style) => {
			  int h, w;
			  if (Gtk.icon_size_lookup_for_settings (s.get_settings (), Gtk.IconSize.MENU, out w, out h)){
					s.set_size_request (w + 2, h + 2);
				}
			});
    
			/* make it as small as possible */
			label.label = text;
			ebox.show_all();
			return ebox;
		} 
        
        private void cb_close_tab()
        {
			
		}
		
		
        private Gtk.Widget ExtractWidget(GLib.Object smartpart)
        {
			Gtk.Widget widget = null;
			 
			if (smartpart is IWidgetProvider)
			{
                stderr.printf("smartpart is IWidgetProvider\n");
                IWidgetProvider iwidgetProvider = smartpart as IWidgetProvider;
                stderr.printf("IWidgetProvider iwidgetProvider = (IWidgetProvider)smartpart;");

                if (iwidgetProvider == null)
                    stderr.printf("iwidgetProvider == null");
                widget = iwidgetProvider.Widget;
                stderr.printf("widget = iwidgetProvider.Widget;");
            }
            
            if (widget == null)
            {
                stderr.printf("widget == null && smartpart is Gtk.Widget\n");
                widget = (Gtk.Widget)smartpart;
            }
            
            return widget;
		}
    }
}
